home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i008: Multi-system program queueing package, Part02/03
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 5f0ab7c9 6a6a7236 2192d719 faf681e1
-
- Submitted-by: Scott Bradner <sob@harvisr.harvard.edu>
- Posting-number: Volume 22, Issue 8
- Archive-name: queuer/part02
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 3)."
- # Contents: com.c defer.c dequeue.c qrm.c queue.1 queue.c queued.5
- # queued.c readconf.c selhost.c showqueue.c
- # Wrapped by rsalz@coconut.bbn.com on Tue May 1 17:18:26 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'com.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'com.c'\"
- else
- echo shar: Extracting \"'com.c'\" \(2927 characters\)
- sed "s/^X//" >'com.c' <<'END_OF_FILE'
- X/* Copyright 1990 The President and Fellows of Harvard University
- X
- XPermission to use, copy, modify, and distribute this program for any
- Xpurpose and without fee is hereby granted, provided that this
- Xcopyright and permission notice appear on all copies and supporting
- Xdocumentation, the name of Harvard University not be used in advertising
- Xor publicity pertaining to distribution of the program, or to results
- Xderived from its use, without specific prior written permission, and notice
- Xbe given in supporting documentation that copying and distribution is by
- Xpermission of Harvard University. Harvard University makes no
- Xrepresentations about the suitability of this software for any purpose.
- XIt is provided "as is" without express or implied warranty. */
- X
- X/* com.c - Dan Lanciani '85 */
- X
- X#include <sgtty.h>
- X#include <stdio.h>
- X#include <signal.h>
- X
- X#include "queue.h"
- X
- Xint tolduser;
- X
- Xcom(s, se)
- X{
- X char buf[BUFSIZ];
- X register int cnt;
- X
- X switch(mode) {
- X
- X case QM_BATCH:
- X if(!tolduser)
- X fprintf(stderr, "Job queued.\n");
- X break;
- X
- X case QM_BACKGROUND:
- X if(se < 0)
- X while((cnt = read(s, buf, BUFSIZ)) > 0)
- X write(1, buf, cnt);
- X else
- X modem(s, se, -1, 1, 2);
- X break;
- X
- X case QM_INTERACTIVE:
- X modem(s, se, 0, 1, 2);
- X break;
- X
- X default:
- X fprintf(stderr, "Bad mode (%d)\n", mode);
- X break;
- X }
- X}
- X
- Xstatic long tmask, emask;
- X
- Xmodem(s, se, i, o, e)
- X{
- X long isample, osample;
- X register int scnt, secnt, tcnt;
- X int t, on = 1;
- X char sbuf[BUFSIZ], sebuf[BUFSIZ], tbuf[BUFSIZ];
- X register char *sp, *sep, *tp;
- X
- X ioctl(s, FIONBIO, &on);
- X scnt = secnt = tcnt = 0;
- X sp = sbuf;
- X sep = sebuf;
- X tp = tbuf;
- X if(i < 0)
- X tmask = 0;
- X else
- X tmask = (1L<<i);
- X emask = (1L<<se);
- X while(1) {
- X isample = osample = 0;
- X if(scnt)
- X osample |= (1L<<o);
- X else
- X isample |= (1L<<s);
- X if(secnt)
- X osample |= (1L<<e);
- X else
- X isample |= emask;
- X if(tcnt)
- X osample |= (1L<<s);
- X else
- X isample |= tmask;
- X if(select(32, &isample, &osample, 0, 0) <= 0)
- X continue;
- X if(isample & (1L<<s))
- X if((scnt = read(s, sbuf, BUFSIZ)) <= 0) {
- X if(scnt < 0)
- X break;
- X close(o);
- X break;
- X }
- X else
- X sp = sbuf;
- X if(isample & (1L<<se))
- X if((secnt = read(se, sebuf, BUFSIZ)) <= 0) {
- X if(secnt < 0)
- X break;
- X close(e);
- X emask = 0;
- X }
- X else
- X sep = sebuf;
- X if(isample & tmask) {
- X if(isatty(i)) {
- X ioctl(i, TIOCGPGRP, &t);
- X if(t != getpgrp(getpid())) {
- X shutdown(s, 1);
- X tmask = 0;
- X continue;
- X }
- X }
- X if((tcnt = read(i, tbuf, BUFSIZ)) <= 0) {
- X if(tcnt < 0)
- X break;
- X shutdown(s, 1);
- X tmask = 0;
- X }
- X else
- X tp = tbuf;
- X }
- X if(osample & (1L<<s)) {
- X t = write(s, tp, tcnt);
- X if(t < 0)
- X break;
- X tcnt -= t;
- X tp += t;
- X }
- X if(osample & (1L<<e)) {
- X t = write(e, sep, secnt);
- X if(t < 0)
- X break;
- X secnt -= t;
- X sep += t;
- X }
- X if(osample & (1L<<o)) {
- X t = write(o, sp, scnt);
- X if(t < 0)
- X break;
- X scnt -= t;
- X sp += t;
- X }
- X }
- X}
- END_OF_FILE
- if test 2927 -ne `wc -c <'com.c'`; then
- echo shar: \"'com.c'\" unpacked with wrong size!
- fi
- # end of 'com.c'
- fi
- if test -f 'defer.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'defer.c'\"
- else
- echo shar: Extracting \"'defer.c'\" \(3845 characters\)
- sed "s/^X//" >'defer.c' <<'END_OF_FILE'
- X/* Copyright 1990 The President and Fellows of Harvard University
- X
- XPermission to use, copy, modify, and distribute this program for any
- Xpurpose and without fee is hereby granted, provided that this
- Xcopyright and permission notice appear on all copies and supporting
- Xdocumentation, the name of Harvard University not be used in advertising
- Xor publicity pertaining to distribution of the program, or to results
- Xderived from its use, without specific prior written permission, and notice
- Xbe given in supporting documentation that copying and distribution is by
- Xpermission of Harvard University. Harvard University makes no
- Xrepresentations about the suitability of this software for any purpose.
- XIt is provided "as is" without express or implied warranty. */
- X
- X
- X/* defer.c - Dan Lanciani '85 */
- X
- X#include <sys/param.h>
- X#include <pwd.h>
- X#include <grp.h>
- X#include <stdio.h>
- X
- Xchar *getenv(), *index(), *rindex(), *malloc();
- XFILE *popen();
- Xstruct passwd *getpwuid();
- Xstruct group *getgrgid();
- X
- Xmain(argc, argv)
- Xchar **argv;
- X{
- X register int i, ng;
- X gid_t groups[NGROUPS];
- X char buf[BUFSIZ], buf1[BUFSIZ], user[30];
- X register char *p;
- X FILE *n, *popen();
- X register struct passwd *pw;
- X register struct group *gr;
- X
- X if((i = getgid()) != getegid()) {
- X if(!(gr = getgrgid(i))) {
- X fprintf(stderr, "What group are you?\n");
- X exit(1);
- X }
- X setenv("GROUP=", gr->gr_name);
- X }
- X ng = getgroups(NGROUPS, groups);
- X setgid(getegid());
- X setgroups(ng, groups);
- X setuid(i = getuid());
- X if(!(pw = getpwuid(i))) {
- X fprintf(stderr, "Who are you?\n");
- X exit(1);
- X }
- X strcpy(user, pw->pw_name);
- X strcat(user, "\t");
- X ng = strlen(user);
- X if(p = rindex(argv[0], '/'))
- X argv[0] = p + 1;
- X for(i = 1; i < argc && argv[i][0] == '-'; i++)
- X setenv("QNOTIFY=", &argv[i][1]);
- X if(argc == i) {
- X printf("Enter command:\n");
- X gets(buf);
- X }
- X else {
- X buf[0] = '\0';
- X for(; i < argc; i++) {
- X strcat(buf, argv[i]);
- X if(i < argc - 1)
- X strcat(buf, " ");
- X }
- X }
- X if(strcmp(argv[0], "defer.long")) {
- X if(n = popen("exec /usr/local/bin/qs bsh", "r")) {
- X i = 0;
- X while(fgets(p = buf1, sizeof(buf1), n)) {
- X if(!(p = index(p, '\t')))
- X continue;
- X if(!(p = index(p + 1, '\t')))
- X continue;
- X if(!strncmp(p + 1, user, ng))
- X i++;
- X }
- X pclose(n);
- X if(i > 2) {
- X fprintf(stderr, "You have 3 queued already\n");
- X exit(1);
- X }
- X }
- X if((p = getenv("SHELL")) && !strcmp(p, "/bin/csh"))
- X execl("/usr/queued_pgms/bcsh", "bcsh", "-c", buf, 0);
- X else
- X execl("/usr/queued_pgms/bsh", "bsh", "-c", buf, 0);
- X }
- X else {
- X if(n = popen("exec /usr/local/bin/qs bsh.long", "r")) {
- X i = 0;
- X while(fgets(p = buf1, sizeof(buf1), n)) {
- X if(!(p = index(p, '\t')))
- X continue;
- X if(!(p = index(p + 1, '\t')))
- X continue;
- X if(!strncmp(p + 1, user, ng))
- X i++;
- X }
- X pclose(n);
- X if(i > 2) {
- X fprintf(stderr, "You have 3 queued already\n");
- X exit(1);
- X }
- X }
- X if((p = getenv("SHELL")) && !strcmp(p, "/bin/csh"))
- X execl("/usr/queued_pgms/bcsh","bcsh.long","-c", buf, 0);
- X else
- X execl("/usr/queued_pgms/bsh", "bsh.long", "-c", buf, 0);
- X }
- X fprintf(stderr, "Can't find queuer?!?\n");
- X exit(1);
- X}
- X
- Xsetenv(var, value)
- Xchar *var, *value;
- X{
- X extern char **environ;
- X char **envnew;
- X int i;
- X int varlen = strlen(var);
- X int vallen = strlen(value);
- X static first = 1;
- X
- X if(first) {
- X first = 0;
- X i = 0;
- X while(environ[i])
- X i++;
- X envnew = (char **) malloc(sizeof (char *) * (i + 1));
- X for(; i >= 0; i--)
- X envnew[i] = environ[i];
- X environ = envnew;
- X }
- X for(i = 0; environ[i]; i++) {
- X if (strncmp(environ[i], var, varlen) == 0) {
- X environ[i] = malloc(varlen + vallen + 1);
- X strcpy(environ[i], var);
- X strcat(environ[i], value);
- X return;
- X }
- X }
- X environ = (char **) realloc(environ, sizeof (char *) * (i + 2));
- X environ[i] = malloc(varlen + vallen + 1);
- X strcpy(environ[i], var);
- X strcat(environ[i], value);
- X environ[++i] = 0;
- X}
- END_OF_FILE
- if test 3845 -ne `wc -c <'defer.c'`; then
- echo shar: \"'defer.c'\" unpacked with wrong size!
- fi
- # end of 'defer.c'
- fi
- if test -f 'dequeue.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dequeue.c'\"
- else
- echo shar: Extracting \"'dequeue.c'\" \(2408 characters\)
- sed "s/^X//" >'dequeue.c' <<'END_OF_FILE'
- X/* Copyright 1990 The President and Fellows of Harvard University
- X
- XPermission to use, copy, modify, and distribute this program for any
- Xpurpose and without fee is hereby granted, provided that this
- Xcopyright and permission notice appear on all copies and supporting
- Xdocumentation, the name of Harvard University not be used in advertising
- Xor publicity pertaining to distribution of the program, or to results
- Xderived from its use, without specific prior written permission, and notice
- Xbe given in supporting documentation that copying and distribution is by
- Xpermission of Harvard University. Harvard University makes no
- Xrepresentations about the suitability of this software for any purpose.
- XIt is provided "as is" without express or implied warranty. */
- X
- X
- X/* dequeue.c - Dan Lanciani '85 */
- X
- X#include <stdio.h>
- X#include <signal.h>
- X
- X#include "queue.h"
- X
- Xdequeue(s)
- X{
- X char buf[BUFSIZ], what[BUFSIZ], prog[BUFSIZ], user[BUFSIZ];
- X register FILE *n, *m;
- X register int i, t, k;
- X register long c, u;
- X
- X for(i = 0; i < 3; i++)
- X dup2(s, i);
- X getstr(s, user);
- X getstr(s, prog);
- X getstr(s, what);
- X if(strcmp(what, "all"))
- X c = atol(what);
- X else
- X c = -1;
- X if(isunid(c)) {
- X sprintf(buf, "%s/%ld", SPOOLDIR, c);
- X if(!(n = fopen(buf, "r")))
- X exit(0);
- X fgetstr(n, buf);
- X fclose(n);
- X if(!(c = atoi(buf)))
- X exit(0);
- X }
- X if(i = readconf(prog)) {
- X fprintf(stderr, "Unknown remote configuration (%d)\n", i);
- X exit(1);
- X }
- X sprintf(buf, "%s/%s", SPOOLDIR, queue);
- X if(!(n = fopen(buf, "r"))) {
- X fprintf(stderr, "Queue file missing\n");
- X exit(1);
- X }
- X while(fgets(buf, sizeof(buf), n))
- X if(c == (k = atoi(buf)) || !c || c == -1) {
- X sprintf(buf, "%s/%d", SPOOLDIR, k);
- X if(!(m = fopen(buf, "r"))) {
- X fprintf(stderr, "Spool file missing (%d)\n", k);
- X continue;
- X }
- X fgetstr(m, buf);
- X fgetstr(m, buf);
- X u = atol(buf);
- X fgetstr(m, buf);
- X t = atoi(buf);
- X for(i = 0; i < t; i++)
- X fgetstr(m, buf);
- X fgetstr(m, buf);
- X if(!c && strcmp(buf, what)) {
- X fclose(m);
- X continue;
- X }
- X if(strcmp(buf, user) && strcmp(user, "root")) {
- X if(u)
- X fprintf(stderr, "Not owner (%s, %ld)\n", buf,u);
- X else
- X fprintf(stderr, "Not owner (%s, %d)\n", buf, k);
- X fclose(m);
- X continue;
- X }
- X kill(k, SIGTERM);
- X if(u)
- X fprintf(stderr, "Killed %ld of %s for %s\n",u,buf,user);
- X else
- X fprintf(stderr, "Killed %d of %s for %s\n", k,buf,user);
- X fclose(m);
- X }
- X fclose(n);
- X exit(0);
- X}
- END_OF_FILE
- if test 2408 -ne `wc -c <'dequeue.c'`; then
- echo shar: \"'dequeue.c'\" unpacked with wrong size!
- fi
- # end of 'dequeue.c'
- fi
- if test -f 'qrm.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'qrm.c'\"
- else
- echo shar: Extracting \"'qrm.c'\" \(2489 characters\)
- sed "s/^X//" >'qrm.c' <<'END_OF_FILE'
- X/* Copyright 1990 The President and Fellows of Harvard University
- X
- XPermission to use, copy, modify, and distribute this program for any
- Xpurpose and without fee is hereby granted, provided that this
- Xcopyright and permission notice appear on all copies and supporting
- Xdocumentation, the name of Harvard University not be used in advertising
- Xor publicity pertaining to distribution of the program, or to results
- Xderived from its use, without specific prior written permission, and notice
- Xbe given in supporting documentation that copying and distribution is by
- Xpermission of Harvard University. Harvard University makes no
- Xrepresentations about the suitability of this software for any purpose.
- XIt is provided "as is" without express or implied warranty. */
- X
- X
- X/* qrm.c - Dan Lanciani '85 */
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <pwd.h>
- X
- X#include "queue.h"
- X
- Xextern int errno;
- Xstruct servent *sp;
- X
- Xmain(argc, argv)
- Xchar **argv;
- X{
- X register struct passwd *pw;
- X register int i, error = 0;
- X
- X if(argc != 3) {
- X fprintf(stderr, "Usage: %s command pid\n", argv[0]);
- X exit(1);
- X }
- X if(!(pw = getpwuid(getuid()))) {
- X fprintf(stderr, "Who are you?\n");
- X exit(1);
- X }
- X if(i = readconf(argv[1])) {
- X fprintf(stderr, "Unknown configuration (%d)\n", i);
- X exit(1);
- X }
- X if(*qm && (sp = getservbyname("qmaster", "tcp")))
- X delq(qm, pw->pw_name, argv[1], argv[2]);
- X if(!(sp = getservbyname("queue", "tcp"))) {
- X fprintf(stderr, "queue: Bad service?!?\n");
- X exit(1);
- X }
- X for(i = 0; i < hcnt; i++)
- X error |= delq(hosts[i], pw->pw_name, argv[1], argv[2]);
- X if(error) {
- X gethostname(host, sizeof(host));
- X delq(host, pw->pw_name, argv[1], argv[2]);
- X }
- X}
- X
- Xdelq(h, u, p, n)
- Xregister char *h, *u, *p, *n;
- X{
- X struct sockaddr_in sin;
- X register struct hostent *hp;
- X int s, trys, i;
- X
- X if(!(hp = gethostbyname(h))) {
- X fprintf(stderr, "%s: Unknown host?!?\n", h);
- X return(1);
- X }
- X trys = 0;
- X i = IPPORT_RESERVED - 1;
- Xretry:
- X if((s = rresvport(&i)) < 0) {
- X perror("rresvport");
- X return(1);
- X }
- X sin.sin_family = hp->h_addrtype;
- X sin.sin_port = sp->s_port;
- X bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
- X if(connect(s, &sin, sizeof(sin))) {
- X close(s);
- X if(trys++ < 5) {
- X sleep(trys);
- X i--;
- X goto retry;
- X }
- X perror("connect");
- X return(1);
- X }
- X write(s, "\2", 1);
- X write(s, u, strlen(u)+1);
- X write(s, p, strlen(p)+1);
- X write(s, n, strlen(n)+1);
- X mode = QM_BACKGROUND;
- X com(s, -1);
- X close(s);
- X return(0);
- X}
- END_OF_FILE
- if test 2489 -ne `wc -c <'qrm.c'`; then
- echo shar: \"'qrm.c'\" unpacked with wrong size!
- fi
- # end of 'qrm.c'
- fi
- if test -f 'queue.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'queue.1'\"
- else
- echo shar: Extracting \"'queue.1'\" \(3326 characters\)
- sed "s/^X//" >'queue.1' <<'END_OF_FILE'
- X.TH QUEUE 1 "11 September 1985"
- X.UC 4
- X.SH NAME
- Xqueue \- transparently queue processes for remote or local execution
- X.SH SYNOPSIS
- X.nf
- Xln queue ``program''
- X``program''
- X.fi
- X.PP
- X.SH DESCRIPTION
- X.I Queue
- Xis never invoked directly, but is always linked to a program that is to
- Xbe queued. The actions taken by
- X.B queue
- Xare controlled by the name with which it is invoked and by a configuration
- Xfile associated with that name. The configuration file is generally set
- Xup to transparently emulate the program which
- X.B queue
- Xreplaces.
- X.PP
- XIn all cases,
- X.B queue
- Xcreates a virtual connection to an instance of the queued(8) daemon which
- Xperforms the actual operation. The daemon may reside on the local host
- Xor on another host which can be reached through the internet. Necessary
- Xfiles (arguments) will be supplied to the daemon and output will be
- Xreturned to the user of
- X.B queue.
- X.PP
- XPrograms run by
- X.B queue
- Xinherit the environment of the invoker, even if the actual execution
- Xtakes place on a remote host. Moreover, certain characteristics may
- Xbe controlled by setting predefined environment variables.
- X.PP
- XThe
- X.B QMAXCPU
- Xenvironment variable places a (lower) ceiling on the number of CPU
- Xseconds that a process may consume. It is useful to prevent runaway
- Xprocesses from using up excessive resources. In no event can the
- X.B QMAXCPU
- Xvariable be used to increase the the cpu time beyond that set in the
- Xprogram's queued configuration file. Similarly, the
- X.B QMAXTIME
- Xenvironment variable places a ceiling on the number of real seconds for
- Xwhich a process may run. This is useful in cases where processes
- Xcould become ``hung,'' accruing no CPU time but blocking the queue.
- X.PP
- XThe
- X.B QMINNICE
- Xenvironment variable alters the base nice (scheduling priority). Increasing
- Xthis variable causes the process to receive a smaller percent of the
- Xcpu resource per unit time. A high ``nice'' should be used for long-running,
- Xnon-time-critical jobs to avoid slowing down the system for interactive users.
- XThe
- X.B QMINNICE
- Xvariable cannot be used to lower the ``nice'' below the value specified
- Xin the program's queued configuration file.
- X.PP
- XThe
- X.B QNOTIFY
- Xvariable sets the method of notification upon completion of batch jobs.
- XIt may be set to "mail" for mail only, to "send" for terminal messages
- Xonly, to "saml" for both, to "soml" for mail only in the event that
- Xterminal messages cannot be delivered, and to "none" for no special
- Xnotification. If not set,
- X.B QNOTIFY
- Xdefaults to "mail." Note that in all cases any errors generated by
- Xthe job will be mailed and that the additional informational mailing
- Xwill be suppressed in these cases.
- X.SH "FILES (/usr/lib/queued/)"
- XQUEUES list of active, local queues
- X.br
- X``program'' configuration file for ``program''
- X.SH "FILES (/usr/spool/queued/)"
- XLOCK master lock node
- X.br
- X``queue'' current information for ``queue''
- X.br
- X``queue''.lock lock on ``queue''
- X.br
- X``queue''.tmp used for rewriting ``queue''
- X.br
- X``pid'' current information for ``pid''
- X.br
- X``pid''.dir temporary execution directory
- X.br
- X``pid''.batch output of batch execution process
- X.SH "FILES (Other)"
- X/usr/adm/qacct queue accounting file
- X.br
- X/etc/hosts.efs hosts with extended file system
- X.br
- X/etc/hosts.flat hosts with one-to-one uid mapping
- X.SH "SEE ALSO"
- Xqrm(1), qs(1), queued(5), queued(8)
- X.SH AUTHOR
- XDan Lanciani
- END_OF_FILE
- if test 3326 -ne `wc -c <'queue.1'`; then
- echo shar: \"'queue.1'\" unpacked with wrong size!
- fi
- # end of 'queue.1'
- fi
- if test -f 'queue.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'queue.c'\"
- else
- echo shar: Extracting \"'queue.c'\" \(6647 characters\)
- sed "s/^X//" >'queue.c' <<'END_OF_FILE'
- X/* Copyright 1990 The President and Fellows of Harvard University
- X
- XPermission to use, copy, modify, and distribute this program for any
- Xpurpose and without fee is hereby granted, provided that this
- Xcopyright and permission notice appear on all copies and supporting
- Xdocumentation, the name of Harvard University not be used in advertising
- Xor publicity pertaining to distribution of the program, or to results
- Xderived from its use, without specific prior written permission, and notice
- Xbe given in supporting documentation that copying and distribution is by
- Xpermission of Harvard University. Harvard University makes no
- Xrepresentations about the suitability of this software for any purpose.
- XIt is provided "as is" without express or implied warranty. */
- X
- X
- X/* queue.c - Dan Lanciani '85 */
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <sys/param.h>
- X#include <sys/stat.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <pwd.h>
- X#include <grp.h>
- X#include <signal.h>
- X
- X#include "queue.h"
- X
- Xextern int errno, botch();
- Xstruct servent *sp;
- Xstruct passwd *pw;
- Xstruct group *gr;
- Xstruct sockaddr_in sin;
- Xlong unid;
- X
- Xmain(argc, argv, envp)
- Xchar **argv, **envp;
- X{
- X register struct optent *p, *op;
- X struct stat statb;
- X register FILE *n;
- X char wd[BUFSIZ], buf[BUFSIZ];
- X int i, s, se = -1, ng, fd, local = 1;
- X gid_t groups[NGROUPS];
- X
- X while((i = open("/dev/null", 2)) < 3);
- X close(i);
- X if(argc < 1) {
- X fprintf(stderr, "No arguments?\n");
- X exit(1);
- X }
- X if(rindex(argv[0], '/'))
- X argv[0] = rindex(argv[0], '/') + 1;
- X if(!(pw = getpwuid(getuid())) || !(gr = getgrgid(getgid()))) {
- X fprintf(stderr, "Who are you?\n");
- X exit(1);
- X }
- X if(!getwd(wd)) {
- X fprintf(stderr, "Can't get current directory\n");
- X exit(1);
- X }
- X if(i = readconf(argv[0])) {
- X fprintf(stderr, "Unknown configuration (%d)\n", i);
- X exit(1);
- X }
- X for(i = 1; i < argc; i++) {
- X op = NULL;
- X for(p = option; p; p = p->op_next) {
- X if(optcmp(p->op_name, argv[i])) {
- X op = p;
- X break;
- X }
- X if(!strcmp(p->op_name, "DEFAULT"))
- X op = p;
- X }
- X if(!op) {
- X fprintf(stderr, "Unknown option (%s)\n", argv[i]);
- X exit(1);
- X }
- X switch(op->op_action) {
- X
- X case OPA_IGNORE:
- X if(!strcmp(op->op_arg, "ARG1"))
- X i++;
- X break;
- X
- X case OPA_COPYIN:
- X p = (struct optent *)malloc(sizeof(struct optent));
- X *p = *op;
- X if(!strcmp(p->op_arg, "ARG0"))
- X p->op_arg = newstring(argv[i]);
- X else if(!strcmp(p->op_arg, "ARG1"))
- X p->op_arg = newstring(argv[++i]);
- X p->op_next = copyin;
- X copyin = p;
- X break;
- X
- X case OPA_COPYOUT:
- X p = (struct optent *)malloc(sizeof(struct optent));
- X *p = *op;
- X if(!strcmp(p->op_arg, "ARG0"))
- X p->op_arg = newstring(argv[i]);
- X else if(!strcmp(p->op_arg, "ARG1"))
- X p->op_arg = newstring(argv[++i]);
- X p->op_next = copyout;
- X copyout = p;
- X break;
- X
- X default:
- X fprintf(stderr, "Bad action (%d)\n", op->op_action);
- X exit(1);
- X }
- X }
- X selhost(argc, argv);
- X if(!(sp = getservbyname("queue", "tcp"))) {
- X fprintf(stderr, "queue: Bad service?!?\n");
- X exit(1);
- X }
- X for(i = 0; i < hcnt; i++)
- X if((s = qconnect(hosts[i])) >= 0) {
- X strcpy(host, hosts[i]);
- X goto found;
- X }
- X if(nolocal) {
- X fprintf(stderr, "No authorized host available\n");
- X fprintf(stderr, "Please contact a staff person.\n");
- X exit(1);
- X }
- X gethostname(host, sizeof(host));
- X if((s = qconnect(host)) < 0) {
- X fprintf(stderr, "Running locally\n");
- X cspawn(prog, argv);
- X wait(0);
- X exit(0);
- X }
- Xfound:
- X gethostname(buf, BUFSIZ);
- X if(strcmp(host, buf) && strcmp(host, "localhost"))
- X local = 0;
- X if(mode == QM_INTERACTIVE) {
- X i = IPPORT_RESERVED - 2;
- X if((se = rresvport(&i)) < 0) {
- X perror("rresvport");
- X exit(1);
- X }
- X listen(se, 1);
- X }
- X else
- X i = 0;
- X setuid(getuid());
- X if(!(n = fdopen(s, "w"))) {
- X perror("fdopen");
- X exit(1);
- X }
- X putc(0, n);
- X fprintf(n, "%d", i);
- X putc('\0', n);
- X fflush(n);
- X if(i) {
- X int fromlen = sizeof(struct sockaddr_in);
- X struct sockaddr_in from;
- X signal(SIGALRM, botch);
- X alarm(30);
- X if((i = accept(se, &from, &fromlen)) < 0) {
- X perror("accept");
- X exit(1);
- X }
- X alarm(0);
- X signal(SIGALRM, SIG_DFL);
- X close(se);
- X se = i;
- X if(ntohs((u_short)from.sin_port) >= IPPORT_RESERVED) {
- X fprintf(stderr, "Protocol failed\n");
- X exit(1);
- X }
- X }
- X fprintf(n, "%ld", unid);
- X putc('\0', n);
- X fprintf(n, "%d", argc);
- X putc('\0', n);
- X for(i = 0; i < argc; i++)
- X xfputs(argv[i], n);
- X xfputs(pw->pw_name, n);
- X xfputs(gr->gr_name, n);
- X ng = getgroups(NGROUPS, groups);
- X fprintf(n, "%d", ng);
- X putc('\0', n);
- X for(i = 0; i < ng; i++)
- X if(gr = getgrgid(groups[i]))
- X xfputs(gr->gr_name, n);
- X else {
- X fprintf(stderr, "Who are you (groups)?\n");
- X exit(1);
- X }
- X xfputs(wd, n);
- X for(ng = 0; envp[ng]; ng++);
- X fprintf(n, "%d", ng);
- X putc('\0', n);
- X for(i = 0; i < ng; i++)
- X xfputs(envp[i], n);
- X if(!local) {
- X if(efs && infile(EFSFILE, host)) {
- X xfputs("efs", n);
- X i = 0;
- X for(p = copyout; p; p = p->op_next)
- X i++;
- X for(p = copyin; p; p = p->op_next)
- X i++;
- X fprintf(n, "%d", i);
- X putc('\0', n);
- X for(p = copyout; p; p = p->op_next) {
- X xfputs(p->op_arg, n);
- X#ifndef SANEEFS
- X#define apath(x) x
- X xfputs(apath(p->op_arg), n);
- X#endif
- X }
- X for(p = copyin; p; p = p->op_next) {
- X xfputs(p->op_arg, n);
- X#ifndef SANEEFS
- X xfputs(apath(p->op_arg), n);
- X#endif
- X }
- X goto nocopy;
- X }
- X if(copyout) {
- X xfputs("copyout", n);
- X i = 0;
- X for(p = copyout; p; p = p->op_next)
- X i++;
- X fprintf(n, "%d", i);
- X putc('\0', n);
- X for(p = copyout; p; p = p->op_next)
- X xfputs(p->op_arg, n);
- X }
- X if(copyin) {
- X xfputs("copyin", n);
- X i = 0;
- X for(p = copyin; p; p = p->op_next)
- X i++;
- X fprintf(n, "%d", i);
- X putc('\0', n);
- X for(p = copyin; p; p = p->op_next) {
- X xfputs(p->op_arg, n);
- X if((fd = open(p->op_arg, 0)) < 0)
- X xfputs("-1", n);
- X else {
- X fstat(fd, &statb);
- X fprintf(n, "%ld", statb.st_size);
- X putc('\0', n);
- X while(1) {
- X i = read(fd, buf, BUFSIZ);
- X if(i <= 0)
- X break;
- X fwrite(buf, sizeof(char), i, n);
- X }
- X close(fd);
- X }
- X }
- X }
- X }
- Xnocopy:
- X xfputs("done", n);
- X fflush(n);
- X com(s, se);
- X}
- X
- Xbotch()
- X{
- X fprintf(stderr, "Protocol timeout\n");
- X exit(1);
- X}
- X
- Xqconnect(h)
- Xchar *h;
- X{
- X int s, trys, i;
- X register struct hostent *hp;
- X
- X if(!(hp = gethostbyname(h))) {
- X fprintf(stderr, "%s: Unknown host?!?\n", h);
- X return(-1);
- X }
- X trys = 0;
- X i = IPPORT_RESERVED - 1;
- Xretry:
- X if((s = rresvport(&i)) < 0) {
- X perror("rresvport");
- X return(-1);
- X }
- X sin.sin_family = hp->h_addrtype;
- X sin.sin_port = sp->s_port;
- X bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
- X if(connect(s, &sin, sizeof(sin))) {
- X close(s);
- X if(trys++ < 5) {
- X sleep(trys);
- X i--;
- X goto retry;
- X }
- X perror("connect");
- X return(-1);
- X }
- X return(s);
- X}
- END_OF_FILE
- if test 6647 -ne `wc -c <'queue.c'`; then
- echo shar: \"'queue.c'\" unpacked with wrong size!
- fi
- # end of 'queue.c'
- fi
- if test -f 'queued.5' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'queued.5'\"
- else
- echo shar: Extracting \"'queued.5'\" \(5413 characters\)
- sed "s/^X//" >'queued.5' <<'END_OF_FILE'
- X.TH QUEUED 5 "24 May 1989"
- X.UC 4
- X.SH NAME
- Xqueued \- format of queued configuration files
- X.SH SYNOPSIS
- Xvi /usr/lib/queued/``program''
- X.PP
- X.SH DESCRIPTION
- XA queued configuration file consists of a series of lines, each beginning
- Xwith a key token. Tokens are optionally followed by arguments separated
- Xby single spaces. Deviations from this format are not accepted. The
- Xfollowing tokens are supported; most have default values, but some are
- Xrequired.
- X.PP
- Xprogram \- required, specifies the program name and its absolute path.
- X.PP
- Xqueue \- required, specifies the queue in which this program runs.
- X.PP
- Xhost \- optional, specifies the host(s) on which to run this program. If
- Xomitted, or if the host specified is not available, the program will
- Xrun locally. If the first character of the hostname is ``/'' then it
- Xis taken instead to be the name of a file containing the actual host
- Xname(s).
- X.PP
- Xqmaster \- optional, specifies a host to maintain a centralized queue
- X.PP
- Xload \- optional, specifies the lower and upper load thresholds for
- Xload-controlled processes. By default, no load-control is done. If
- Xlower and upper thresholds are the same, a process will not be started
- Xuntil the load is lower than the limit, but no further attempt will
- Xbe made to load-control the process. If the thresholds are different,
- Xthe first (lower) is the load value at which the process will be started
- Xand the second (higher) is the load value at which the process will be
- Xstopped. All loads are specified in units of CPU/100; a load of
- X2.34 would be written as 234.
- X.PP
- Xminnice \- optional, specifies a minimum ``nice'' at which to run
- Xthe program. Default is zero. A user may increase the nice for his
- Xjobs by setting the QMINNICE environment variable.
- X.PP
- Xmaxcpu \- optional, specifies the maximum cpu time in seconds that may be
- Xused by any process run by the program. Default is no limit. A user may
- Xdecrease the cpu time allowed for his jobs by setting the QMAXCPU environment
- Xvariable.
- X.PP
- Xmaxtime \- optional, specifies the maximum real time in seconds that
- Xthe program will be allowed to run. Default is no limit. A user may
- Xdecrease the real time allowed for his jobs by setting the QMAXTIME
- Xenvironment variable. The maxtime option is not recommended for use
- Xin conjunction with load control.
- X.PP
- Xmaxrun \- optional, specifies the maximum number of programs that
- Xmay run at one time, on one host. Default is one.
- X.PP
- Xmaxperu \- optional, specifies the maximum number of programs that
- Xmay be enqueued at one time, by one user. Default is no limit. This
- Xoption is effective only in conjunction with a qmaster.
- X.PP
- Xmode \- required, specifies the mode, which may be one of background
- X(for programs that will not need to read standard input), interactive
- X(for programs that may read standard input), or batch (for programs
- Xthat can be run completely detached from the user, with results
- Xmailed back at completion.
- X.PP
- Xnolocal \- optional, prevents local execution even if no servers
- Xare available. This option will not override a host specification.
- X.PP
- Xefs \- optional, allows an extended file system, if available, to
- Xreplace the normal file copying operation.
- X.PP
- Xrestart \- optional, indicates that this job should be restarted
- Xafter a system crash.
- X.PP
- Xcopyin \- optional, specifies a file that must be transported to
- Xthe machine on which the program is executed either by copying or
- Xby use of an extended file system. Only one file name argument
- Xis allowed, but there may be any number of copyin lines in each
- Xconfiguration file.
- X.PP
- Xcopyout \- optional, specifies a file that must be transported back
- Xfrom the machine on which the program is executed by use of an
- Xextended file system. Only one file name argument is allowed, but there
- Xmay be any number of copyout lines in each configuration file. Note
- Xthat if no extended file system is available, use of copyout is
- Xsomewhat restricted.
- X.PP
- Xoption \- optional, specifies an option to the program and possible
- Xactions that should be taken when that option is encountered. In its
- Xsimplest form, option takes a single argument which is the name of
- Xthe option to be ignored. A trailing asterisk in the option name
- Xserves as a simple wild-card. An option name of ``DEFAULT'' will
- Xmatch any option which cannot otherwise be matched. Any of these
- Xforms may be followed by a copyin or copyout statement which
- Xbehaves as described above, but conditionalized on the presence
- Xof the specified option. Finally, when used in this way, copyin
- Xand copyout may specify the magic tokens ARG0 and ARG1 instead
- Xof file names. These indicate, respectively, that the file to be
- Xtransported is the option itself or the argument immediately following
- Xit.
- X.SH "FILES (/usr/lib/queued/)"
- XQUEUES list of active, local queues
- X.br
- X``program'' configuration file for ``program''
- X.SH "FILES (/usr/spool/queued/)"
- XLOCK master lock node
- X.br
- X``queue'' current information for ``queue''
- X.br
- X``queue''.lock lock on ``queue''
- X.br
- X``queue''.tmp used for rewriting ``queue''
- X.br
- X``pid'' current information for ``pid''
- X.br
- X``pid''.dir temporary execution directory
- X.br
- X``pid''.batch output of batch execution process
- X.SH "FILES (Other)"
- X/usr/adm/qacct queue accounting file
- X.br
- X/etc/hosts.efs hosts with extended file system
- X.br
- X/etc/hosts.flat hosts with one-to-one uid mapping
- X.SH "SEE ALSO"
- Xqrm(1), qs(1), queue(1), queued(8)
- X.SH AUTHOR
- XDan Lanciani
- END_OF_FILE
- if test 5413 -ne `wc -c <'queued.5'`; then
- echo shar: \"'queued.5'\" unpacked with wrong size!
- fi
- # end of 'queued.5'
- fi
- if test -f 'queued.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'queued.c'\"
- else
- echo shar: Extracting \"'queued.c'\" \(5767 characters\)
- sed "s/^X//" >'queued.c' <<'END_OF_FILE'
- X/* Copyright 1990 The President and Fellows of Harvard University
- X
- XPermission to use, copy, modify, and distribute this program for any
- Xpurpose and without fee is hereby granted, provided that this
- Xcopyright and permission notice appear on all copies and supporting
- Xdocumentation, the name of Harvard University not be used in advertising
- Xor publicity pertaining to distribution of the program, or to results
- Xderived from its use, without specific prior written permission, and notice
- Xbe given in supporting documentation that copying and distribution is by
- Xpermission of Harvard University. Harvard University makes no
- Xrepresentations about the suitability of this software for any purpose.
- XIt is provided "as is" without express or implied warranty. */
- X
- X
- X/* queued.c - Dan Lanciani '85 */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/wait.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <errno.h>
- X#include <signal.h>
- X#include <sgtty.h>
- X
- X#include "queue.h"
- X
- Xstruct sockaddr_in sin = { AF_INET };
- Xextern int errno;
- Xint reapchild();
- X
- Xmain(argc, argv, envp)
- Xchar **argv, **envp;
- X{
- X struct servent *sp;
- X int s, on = 1;
- X char buf[BUFSIZ], tbuf[BUFSIZ];
- X FILE *n, *m;
- X
- X#ifndef DEBUG
- X for(s = 0; s < 30; s++)
- X close(s);
- X if((s = open("/dev/tty", 2)) >= 0) {
- X ioctl(s, TIOCNOTTY, 0);
- X close(s);
- X }
- X if((s = open("/dev/console", 2)) >= 0) {
- X close(s);
- X setpgrp(0, 0);
- X }
- X s = open("/", 0);
- X dup(s);
- X dup(s);
- X signal(SIGALRM, SIG_IGN);
- X signal(SIGPIPE, SIG_IGN);
- X if(fork())
- X exit(0);
- X#endif
- X
- X if(!(sp = getservbyname("queue", "tcp"))) {
- X fprintf(stderr, "queue: Bad service?!?\n");
- X exit(1);
- X }
- X if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- X perror("socket");
- X exit(1);
- X }
- X setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
- X setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
- X sin.sin_port = sp->s_port;
- X if(bind(s, &sin, sizeof(sin))) {
- X perror("bind");
- X exit(1);
- X }
- X listen(s, 10);
- X if(n = fopen(QUEUES, "r")) {
- X while(fgets(buf, sizeof(buf), n)) {
- X buf[strlen(buf)-1] = '\0';
- X sprintf(tbuf, "%s/%s", SPOOLDIR, buf);
- X if(m = fopen(tbuf, "r")) {
- X unlink(tbuf);
- X creat(tbuf, 0644);
- X while(fgets(buf, sizeof(buf), m)) {
- X buf[strlen(buf)-1] = '\0';
- X if(!fork()) {
- X close(s);
- X fclose(m);
- X fclose(n);
- X recover(buf);
- X exit(0);
- X }
- X }
- X fclose(m);
- X }
- X else
- X creat(tbuf, 0644);
- X }
- X fclose(n);
- X }
- X while(1) {
- X struct sockaddr_in from;
- X int pid, s0, fromlen;
- X signal(SIGCHLD, reapchild);
- X fromlen = sizeof(from);
- X if((s0 = accept(s, &from, &fromlen)) < 0) {
- X if(errno = EINTR)
- X continue;
- X perror("accept");
- X exit(1);
- X }
- X if(from.sin_family != AF_INET ||
- X htons((u_short)from.sin_port) >= IPPORT_RESERVED ||
- X htons((u_short)from.sin_port) < IPPORT_RESERVED / 2) {
- X close(s0);
- X continue;
- X }
- X if((pid = fork()) < 0) {
- X perror("fork");
- X exit(1);
- X }
- X if(!pid) {
- X signal(SIGCHLD, SIG_DFL);
- X signal(SIGALRM, SIG_DFL);
- X signal(SIGPIPE, SIG_DFL);
- X close(s);
- X doit(s0, &from);
- X exit(0);
- X }
- X close(s0);
- X }
- X}
- X
- Xreapchild()
- X{
- X union wait status;
- X char buf[BUFSIZ], name1[BUFSIZ], name2[BUFSIZ];
- X FILE *n, *m;
- X register int pid, i;
- X long unid;
- X
- X while((pid = wait3(&status, WNOHANG, 0)) > 0) {
- X sprintf(buf, "%s/%d", SPOOLDIR, pid);
- X if(n = fopen(buf, "r")) {
- X unlink(buf);
- X fgetstr(n, buf);
- X fgetstr(n, buf);
- X unid = atol(buf);
- X fgetstr(n, buf);
- X fgetstr(n, buf);
- X fclose(n);
- X if(!fork()) {
- X signal(SIGCHLD, SIG_DFL);
- X for(i = 0; i < 30; i++)
- X close(i);
- X if(readconf(buf))
- X exit(1);
- X if(unid) {
- X sprintf(buf, "%s/%ld", SPOOLDIR, unid);
- X unlink(buf);
- X }
- X sprintf(buf, "%s/%d.dir", SPOOLDIR, pid);
- X if(!access(buf, 0)) {
- X if(!vfork()) {
- X execl("/bin/rm", "rm", "-rf", buf, 0);
- X exit(1);
- X }
- X wait(0);
- X }
- X sprintf(buf, "%s/%d.batch", SPOOLDIR, pid);
- X unlink(buf);
- X sprintf(buf, "%s/%d.ebatch", SPOOLDIR, pid);
- X unlink(buf);
- X sprintf(name1, "%s/%s", SPOOLDIR, queue);
- X lock(name1);
- X n = fopen(name1, "r");
- X strcpy(name2, name1);
- X strcat(name2, ".tmp");
- X m = fopen(name2, "w");
- X i = 0;
- X while(fgets(buf, sizeof(buf), n))
- X if(atoi(buf) != pid) {
- X if(i++ < maxrun)
- X kill(atoi(buf), SIGALRM);
- X fputs(buf, m);
- X }
- X fclose(m);
- X fclose(n);
- X unlink(name1);
- X link(name2, name1);
- X unlink(name2);
- X unlock(name1);
- X exit(0);
- X }
- X }
- X }
- X}
- X
- Xdoit(s, sin)
- Xstruct sockaddr_in *sin;
- X{
- X struct hostent *hp;
- X char buf[BUFSIZ];
- X
- X if(!(hp=gethostbyaddr(&sin->sin_addr, sizeof(struct in_addr), AF_INET)))
- X exit(1);
- X if(index(hp->h_name, '.'))
- X *index(hp->h_name, '.') = '\0';
- X gethostname(buf, BUFSIZ);
- X if(!strcmp(hp->h_name, "localhost")) {
- X qservice(s, buf, sin, 1);
- X exit(0);
- X }
- X if(!strcmp(hp->h_name, buf)) {
- X qservice(s, buf, sin, 1);
- X exit(0);
- X }
- X if(infile(EQUIVFILE, hp->h_name)) {
- X qservice(s, hp->h_name, sin, 0);
- X exit(0);
- X }
- X exit(1);
- X}
- X
- Xqservice(s, host, sin, local)
- Xchar *host;
- Xstruct sockaddr_in *sin;
- X{
- X char request;
- X
- X if(read(s, &request, 1) != 1)
- X exit(1);
- X switch(request&0377) {
- X
- X case 0:
- X enqueue(s, host, sin, local, 0);
- X break;
- X
- X case 1:
- X showqueue(s, host, sin, local);
- X break;
- X
- X case 2:
- X dequeue(s, host, sin, local);
- X break;
- X
- X default:
- X exit(1);
- X break;
- X }
- X}
- X
- Xrecover(job)
- Xchar *job;
- X{
- X int s;
- X char buf1[BUFSIZ], buf2[BUFSIZ];
- X
- X sprintf(buf2, "%s/%d", SPOOLDIR, atoi(job));
- X if((s = open(buf2, 0)) < 0)
- X exit(0);
- X unlink(buf2);
- X sprintf(buf1, "%s/%d.dir", SPOOLDIR, getpid());
- X sprintf(buf2, "%s/%d.dir", SPOOLDIR, atoi(job));
- X rename(buf2, buf1);
- X sprintf(buf2, "%s/%d.batch", SPOOLDIR, atoi(job));
- X unlink(buf2);
- X sprintf(buf2, "%s/%d.ebatch", SPOOLDIR, atoi(job));
- X unlink(buf2);
- X enqueue(s, 0, 0, 0, 1);
- X exit(1);
- X}
- END_OF_FILE
- if test 5767 -ne `wc -c <'queued.c'`; then
- echo shar: \"'queued.c'\" unpacked with wrong size!
- fi
- # end of 'queued.c'
- fi
- if test -f 'readconf.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'readconf.c'\"
- else
- echo shar: Extracting \"'readconf.c'\" \(4684 characters\)
- sed "s/^X//" >'readconf.c' <<'END_OF_FILE'
- X/* Copyright 1990 The President and Fellows of Harvard University
- X
- XPermission to use, copy, modify, and distribute this program for any
- Xpurpose and without fee is hereby granted, provided that this
- Xcopyright and permission notice appear on all copies and supporting
- Xdocumentation, the name of Harvard University not be used in advertising
- Xor publicity pertaining to distribution of the program, or to results
- Xderived from its use, without specific prior written permission, and notice
- Xbe given in supporting documentation that copying and distribution is by
- Xpermission of Harvard University. Harvard University makes no
- Xrepresentations about the suitability of this software for any purpose.
- XIt is provided "as is" without express or implied warranty. */
- X
- X
- X/* readconf.c - Dan Lanciani '85 */
- X
- X#include <stdio.h>
- X#include "queue.h"
- X
- Xchar prog[BUFSIZ], host[BUFSIZ], qm[BUFSIZ], queue[BUFSIZ];
- Xchar *hosts[MAXHCNT];
- Xint maxcpu, minnice, maxrun, minload, maxload, mode, priv, efs, restart;
- Xint hcnt, maxtime, nolocal, maxperu;
- Xstruct optent *copyin = NULL;
- Xstruct optent *copyout = NULL;
- Xstruct optent *option = NULL;
- X
- Xreadconf(p)
- Xchar *p;
- X{
- X register FILE *n, *m;
- X char name[BUFSIZ], buf[BUFSIZ], action[BUFSIZ], arg[BUFSIZ];
- X register int i;
- X register struct optent *op;
- X
- X sprintf(name, "%s/%s", LIBDIR, p);
- X if(!(n = fopen(name, "r")))
- X return(-1);
- X if(fscanf(n, "%s %s %s\n", buf, name, prog) != 3) {
- X fclose(n);
- X return(-2);
- X }
- X if(strcmp(buf, "program") || strcmp(name, p)) {
- X fclose(n);
- X return(-3);
- X }
- X gethostname(host, BUFSIZ);
- X qm[0] = '\0';
- X strcpy(queue, "test");
- X maxcpu = 0;
- X minnice = 0;
- X maxrun = 1;
- X minload = maxload = 0;
- X mode = QM_BACKGROUND;
- X priv = 0;
- X efs = 0;
- X restart = 0;
- X hcnt = 0;
- X maxtime = 0;
- X nolocal = 0;
- X maxperu = 0;
- X if(p = getenv("QMAXCPU"))
- X maxcpu = atoi(p);
- X if(p = getenv("QMINNICE"))
- X minnice = atoi(p);
- X if(p = getenv("QMAXTIME"))
- X maxtime = atoi(p);
- X if(minnice < 0)
- X minnice = 0;
- X while(fgets(buf, sizeof(buf), n)) {
- X buf[strlen(buf)-1] = '\0';
- X if(!strncmp(buf, "copyin ", 7)) {
- X op = (struct optent *)malloc(sizeof(struct optent));
- X op->op_action = OPA_COPYIN;
- X op->op_arg = newstring(buf+7);
- X op->op_next = copyin;
- X copyin = op;
- X continue;
- X }
- X if(!strncmp(buf, "copyout ", 8)) {
- X op = (struct optent *)malloc(sizeof(struct optent));
- X op->op_action = OPA_COPYOUT;
- X op->op_arg = newstring(buf+8);
- X op->op_next = copyout;
- X copyout = op;
- X continue;
- X }
- X if(!strncmp(buf, "option ", 7)) {
- X i = sscanf(buf+7, "%s %s %s", name, action, arg);
- X if(!i)
- X continue;
- X op = (struct optent *)malloc(sizeof(struct optent));
- X op->op_name = newstring(name);
- X if(i != 3) {
- X op->op_action = OPA_IGNORE;
- X op->op_arg = "ARG0";
- X }
- X else {
- X if(!strcmp(action, "copyin"))
- X op->op_action = OPA_COPYIN;
- X else if(!strcmp(action, "copyout"))
- X op->op_action = OPA_COPYOUT;
- X else op->op_action = OPA_IGNORE;
- X op->op_arg = newstring(arg);
- X }
- X op->op_next = option;
- X option = op;
- X continue;
- X }
- X if(!strncmp(buf, "host ", 5)) {
- X strcpy(host, buf+5);
- X if(host[0] == '/' && (m = fopen(host, "r"))) {
- X while(fgets(host, sizeof(host), m)) {
- X host[strlen(host)-1] = '\0';
- X if(hcnt < MAXHCNT)
- X hosts[hcnt++] = newstring(host);
- X }
- X fclose(m);
- X }
- X else
- X if(hcnt < MAXHCNT)
- X hosts[hcnt++] = newstring(host);
- X continue;
- X }
- X if(!strncmp(buf, "qmaster ", 8)) {
- X strcpy(qm, buf+8);
- X continue;
- X }
- X if(!strncmp(buf, "maxcpu ", 7)) {
- X if((i = atoi(buf+7)) < maxcpu || !maxcpu)
- X maxcpu = i;
- X continue;
- X }
- X if(!strncmp(buf, "minnice ", 8)) {
- X if((i = atoi(buf+8)) > minnice)
- X minnice = i;
- X continue;
- X }
- X if(!strncmp(buf, "maxtime ", 8)) {
- X if((i = atoi(buf+8)) < maxtime || !maxtime)
- X maxtime = i;
- X continue;
- X }
- X if(!strncmp(buf, "maxrun ", 7)) {
- X maxrun = atoi(buf+7);
- X continue;
- X }
- X if(!strncmp(buf, "load ", 5)) {
- X sscanf(buf+5, "%d %d", &minload, &maxload);
- X continue;
- X }
- X if(!strncmp(buf, "mode ", 5)) {
- X if(!strcmp(buf+5, "batch"))
- X mode = QM_BATCH;
- X else if(!strcmp(buf+5, "background"))
- X mode = QM_BACKGROUND;
- X else if(!strcmp(buf+5, "interactive"))
- X mode = QM_INTERACTIVE;
- X continue;
- X }
- X if(!strncmp(buf, "queue ", 6)) {
- X strcpy(queue, buf+6);
- X continue;
- X }
- X if(!strcmp(buf, "magic")) {
- X priv = 1;
- X continue;
- X }
- X if(!strcmp(buf, "efs")) {
- X efs = 1;
- X continue;
- X }
- X if(!strcmp(buf, "restart")) {
- X restart = 1;
- X continue;
- X }
- X if(!strcmp(buf, "nolocal")) {
- X nolocal = 1;
- X continue;
- X }
- X if(!strncmp(buf, "maxperu ", 8)) {
- X maxperu = atoi(buf+8);
- X continue;
- X }
- X }
- X fclose(n);
- X if(!hcnt)
- X hosts[hcnt++] = newstring(host);
- X hosts[hcnt] = 0;
- X return(0);
- X}
- END_OF_FILE
- if test 4684 -ne `wc -c <'readconf.c'`; then
- echo shar: \"'readconf.c'\" unpacked with wrong size!
- fi
- # end of 'readconf.c'
- fi
- if test -f 'selhost.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'selhost.c'\"
- else
- echo shar: Extracting \"'selhost.c'\" \(3654 characters\)
- sed "s/^X//" >'selhost.c' <<'END_OF_FILE'
- X/* Copyright 1990 The President and Fellows of Harvard University
- X
- XPermission to use, copy, modify, and distribute this program for any
- Xpurpose and without fee is hereby granted, provided that this
- Xcopyright and permission notice appear on all copies and supporting
- Xdocumentation, the name of Harvard University not be used in advertising
- Xor publicity pertaining to distribution of the program, or to results
- Xderived from its use, without specific prior written permission, and notice
- Xbe given in supporting documentation that copying and distribution is by
- Xpermission of Harvard University. Harvard University makes no
- Xrepresentations about the suitability of this software for any purpose.
- XIt is provided "as is" without express or implied warranty. */
- X
- X
- X/* selhost.c - Dan Lanciani '85 '89 */
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <stdio.h>
- X#include <netdb.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X#include <pwd.h>
- X#include "queue.h"
- X
- Xextern struct servent *sp;
- Xextern struct passwd *pw;
- Xextern long unid;
- Xextern int tolduser;
- Xstatic jmp_buf jb;
- X
- Xstatic struct ht {
- X char *ht_name;
- X int ht_load;
- X} ht[MAXHCNT];
- X
- Xstatic
- Xcmp(a, b)
- Xstruct ht *a, *b;
- X{
- X return(a->ht_load - b->ht_load);
- X}
- X
- Xstatic
- Xcatch()
- X{
- X longjmp(jb, 1);
- X}
- X
- Xstatic char *
- Xngetstr(n, buf)
- Xchar *buf;
- X{
- X register char *p = buf;
- X
- X do
- X if(read(n, p, 1) != 1)
- X return(0);
- X while(*p++);
- X return(buf);
- X}
- X
- Xstatic char *argv0;
- X
- Xstatic
- Xdoqrm()
- X{
- X char buf[20];
- X
- X if(argv0 && unid) {
- X sprintf(buf, "%ld", unid);
- X execl("/usr/local/bin/qrm", "qrm", argv0, buf, 0);
- X }
- X exit(-1);
- X}
- X
- Xselhost(argc, argv)
- Xchar **argv;
- X{
- X register int i, s, u;
- X int sz;
- X unsigned char buf[BUFSIZ];
- X struct sockaddr_in sin;
- X
- X argv0 = argv[0];
- X if(hcnt < 2 && !*qm)
- X return;
- X for(i = 0; i < hcnt; i++) {
- X ht[i].ht_name = hosts[i];
- X ht[i].ht_load = getrload(hosts[i]);
- X }
- X qsort((char *)ht, hcnt, sizeof(ht[0]), cmp);
- X for(i = 0; i < hcnt; i++)
- X hosts[i] = ht[i].ht_name;
- X if(!*qm || !(sp = getservbyname("qmaster", "tcp")) ||(s=qconnect(qm))<0)
- X return;
- X if((u = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- X perror("socket");
- X close(s);
- X return;
- X }
- X bzero(&sin, sizeof(sin));
- X if(bind(u, &sin, sizeof(sin))) {
- X perror("bind");
- X close(u);
- X close(s);
- X return;
- X }
- X sz = sizeof(sin);
- X if(getsockname(u, &sin, &sz)) {
- X perror("getsockname");
- X close(u);
- X close(s);
- X return;
- X }
- X if(setjmp(jb)) {
- X out:
- X alarm(0);
- X signal(SIGALRM, SIG_DFL);
- X close(u);
- X if(s >= 0)
- X close(s);
- X signal(SIGPIPE, SIG_DFL);
- X return;
- X }
- X signal(SIGALRM, catch);
- X alarm(5*60);
- X signal(SIGPIPE, SIG_IGN);
- X *buf = 0;
- X sprintf(buf + 1, "%d", sin.sin_port);
- X write(s, buf, strlen(buf + 1) + 2);
- X write(s, argv0, strlen(argv0) + 1);
- X write(s, pw->pw_name, strlen(pw->pw_name) + 1);
- X signal(SIGPIPE, SIG_DFL);
- X if(read(s, buf, 1) != 1)
- X goto out;
- X i = *buf;
- X if(!ngetstr(s, buf))
- X goto out;
- X if(i == 1) {
- X fprintf(stderr, "%s\n", buf);
- X exit(1);
- X }
- X unid = atol(buf);
- X if(!isunid(unid)) {
- X unid = 0;
- X goto out;
- X }
- X close(s);
- X s = -1;
- X alarm(0);
- X if(mode == QM_BATCH) {
- X tolduser++;
- X if(fork()) {
- X fprintf(stderr, "Job queued.\n");
- X exit(0);
- X }
- X }
- X signal(SIGINT, doqrm);
- X alarm(5*60);
- X while(1) {
- X sz = sizeof(sin);
- X if(recvfrom(u, buf, sizeof(buf), 0, &sin, &sz) <= 0) {
- X i = alarm(0);
- X sleep(10);
- X alarm(i);
- X continue;
- X }
- X switch(*buf) {
- X case 0:
- X alarm(5*60);
- X continue;
- X case 1:
- X alarm(0);
- X signal(SIGALRM, SIG_DFL);
- X close(u);
- X i = hcnt;
- X if(i == MAXHCNT)
- X i--;
- X while(i) {
- X hosts[i] = hosts[i - 1];
- X i--;
- X }
- X hosts[0] = newstring(buf + 1);
- X return;
- X case 2:
- X exit(0);
- X default:
- X goto out;
- X }
- X }
- X}
- END_OF_FILE
- if test 3654 -ne `wc -c <'selhost.c'`; then
- echo shar: \"'selhost.c'\" unpacked with wrong size!
- fi
- # end of 'selhost.c'
- fi
- if test -f 'showqueue.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'showqueue.c'\"
- else
- echo shar: Extracting \"'showqueue.c'\" \(2471 characters\)
- sed "s/^X//" >'showqueue.c' <<'END_OF_FILE'
- X/* Copyright 1990 The President and Fellows of Harvard University
- X
- XPermission to use, copy, modify, and distribute this program for any
- Xpurpose and without fee is hereby granted, provided that this
- Xcopyright and permission notice appear on all copies and supporting
- Xdocumentation, the name of Harvard University not be used in advertising
- Xor publicity pertaining to distribution of the program, or to results
- Xderived from its use, without specific prior written permission, and notice
- Xbe given in supporting documentation that copying and distribution is by
- Xpermission of Harvard University. Harvard University makes no
- Xrepresentations about the suitability of this software for any purpose.
- XIt is provided "as is" without express or implied warranty. */
- X
- X
- X/* showqueue.c - Dan Lanciani '85 */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#include "queue.h"
- X
- Xshowqueue(s)
- X{
- X struct stat statb;
- X char buf[BUFSIZ], tbuf[BUFSIZ], lhost[BUFSIZ];
- X register FILE *n, *m, *l;
- X register int i, c, oneonly = 0;
- X
- X gethostname(lhost, BUFSIZ);
- X for(i = 0; i < 3; i++)
- X dup2(s, i);
- X getstr(s, buf);
- X if(s > 2)
- X close(s);
- X if(*buf) {
- X oneonly++;
- X goto onlyone;
- X }
- X if(!(n = fopen(QUEUES, "r"))) {
- X fprintf(stderr, "No QUEUES file\n");
- X exit(1);
- X }
- X
- X while(fgets(buf, sizeof(buf), n)) {
- X buf[strlen(buf)-1] = '\0';
- X onlyone:
- X printf("Queue: %s, Host: %s\n", buf, lhost);
- X sprintf(tbuf, "%s/%s", SPOOLDIR, buf);
- X if(m = fopen(tbuf, "r")) {
- X printf("Pid\t\tState\tUser\tHost\tCommand\n");
- X while(fgets(buf, sizeof(buf), m)) {
- X buf[strlen(buf)-1] = '\0';
- X i = atoi(buf);
- X sprintf(tbuf, "%s/%s", SPOOLDIR, buf);
- X if(l = fopen(tbuf, "r")) {
- X fgetstr(l, buf);
- X fgetstr(l, buf);
- X if(atol(buf))
- X printf("%-16ld", atol(buf));
- X else
- X printf("%-16d", i);
- X if(!fstat(fileno(l), &statb) &&
- X (statb.st_mode&0111))
- X printf("RUN\t");
- X else
- X printf("WAIT\t");
- X fgetstr(l, buf);
- X c = atoi(buf);
- X for(i = 0; i < c; i++)
- X fgetstr(l, buf);
- X fgetstr(l, buf);
- X printf("%s\t", buf);
- X rewind(l);
- X fgetstr(l, buf);
- X printf("%s\t", buf);
- X fgetstr(l, buf);
- X fgetstr(l, buf);
- X c = atoi(buf);
- X for(i = 0; i < c; i++) {
- X fgetstr(l, buf);
- X printf("%s ", buf);
- X }
- X fclose(l);
- X printf("\n");
- X }
- X }
- X printf("\n");
- X fclose(m);
- X }
- X else
- X printf("Warning: File missing\n\n");
- X fflush(stdout);
- X if(oneonly)
- X exit(0);
- X }
- X fclose(n);
- X}
- END_OF_FILE
- if test 2471 -ne `wc -c <'showqueue.c'`; then
- echo shar: \"'showqueue.c'\" unpacked with wrong size!
- fi
- # end of 'showqueue.c'
- fi
- echo shar: End of archive 2 \(of 3\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- exit 0 # Just in case...
-